chat: onboarding answers the pointer and a second enter, no telemetry notice or command, and free models only on a low account - #1720
Conversation
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
6bff8fc to
8576e80
Compare
… notice or command, and free models only on a low account Santosh's first-run notes (2026-09-30), the non-Teams half. - The welcome screen's starting points took every enter: the first filled the box, the second did nothing — four of five new people read that as enter not working. With words in the box, enter is the composer's. - The Models and spending screen swallowed every press; its rows now act like the key they stand for (a press on the model row opens the list, on a model takes it, on Start leaves), the wheel scrolls the open list, and enter goes on after a model is taken or a review is shown, so enter alone walks the whole form. - The six-line usage-counts notice is gone from the first conversation's screen, from --once and from task commands, and the send gate on it with it; `codeaf telemetry` (status, info, show, on, off) is removed. The disclosure is README.md and docs/TELEMETRY.md; the switches are the settings sheet's telemetry row, CODEAF_TELEMETRY, DO_NOT_TRACK and the project file, unchanged. - While the OpenRouter account reads low, the setup's chat-model list is cut to free rows, says `free only`, and a line under the field says why. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…message box and on the setup screen A balance read that OpenRouter answered with `API key expired` was a failed read: nothing recorded, nothing said, and the next turn failed with a plain auth error. The 401 that says expired is now a reading of its own (credits.Reading.Expired, kept beside low in credits.json): `Your OpenRouter key has expired — make a new one at openrouter.ai/settings/keys` stands at the right of the keys row in a conversation and on Home for every model the default service serves, free included, and under the chat model on the setup screen, where the list is not cut because the free rows fail on the same key. A turn refused as expired asks for a fresh read, through a fact stamped on the provider's refusal (APIError.KeyExpired) so no surface reads the status for itself. A new key clears it before it is read. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… window allows The example was a second column beside the form, 36 cells wide, drawn from 112 columns up and level with the first field: on a tall window the lower half of the screen stayed empty while the panel wrapped every sentence three ways. It is one column now — the form, its keys line, one blank row, then the panel at up to 92 cells, whole or not at all. A window with no rows to spare under the form draws the form alone and the keys line stops naming the arrows. The form is 64 cells on every window. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ts title on its edge, and shows a /senior-dev hand-off Under the form, the legend stood between the form and the panel and read as a caption for the wrong one. The order is now the panel, two blank rows, the keys line, and the form directly under it. The panel's top edge reads `○ Example · <the example's title>` and the title is no longer a row of the body. A fifth example, `Hand off complex coding tasks`, asks `/senior-dev Add retries with backoff to the HTTP client, with tests.` beside `Start a conversation`, and a command in any example's request wears the composer's chip. The keys line says `enter sets the limit` on the limit row and `↑↓ moves` in place of `tab moves` everywhere; the tmux suite's needle follows it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…t, the panel loses its foot line, and the account's warning rides the frame's foot `Models and spending` over `Keep these choices or change them.` is one line, `Basic settings`, and the keys line is the row directly under it rather than the foot of the form. The keys line no longer names the example's arrows: the panel's own bottom edge carries them. The panel no longer ends on `An illustration. Nothing here has run.`; its `Example` label says that once. The low-credits and expired-key lines leave the chat-model row and stand right-aligned on the frame's last row, where the keys row carries the same warning outside the setup; the expired-key line is shortened to fit any window the panel fits. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…grey once answered, white until then `→` on the last example is the first again, and `←` on the first the last. Every row's name — the limit, the chat model, the review, the way out — is painted by one rule: the accent while the focus is on it, dim once enter has acted on it (the limit set, a model taken from the list, the review shown), and the body ink until then. Opening the list and leaving it with esc answers nothing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Each row was the catalog's friendly name with the exact id drawn under the cursor's row, which read as a heading with a subheading and made the one row a person could act on two rows tall. Each row is the id now, one row per model; typing still finds a model by its friendly name and the field above still shows it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…t points at /settings `Other settings use defaults · review` showed three settings and let nobody change them — a door painted on a wall, and people pressed on it. The form is three rows now: the limit, the chat model, the way out. Under `Start a conversation` one dim line reads `Everything else is in /settings`, with the command painted as the composer's chip. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ut carries no loose enter The limit's line ends `/budget changes it later.` and the chat model's `/model changes it later.`, each command painted as the composer's chip the way the note's /settings is. The dim `enter` at the right of `Start a conversation` is gone: the keys line under the heading already says `enter starts` when the focus is there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…and never follow the focus The panel followed the focused row, which read as it jumping about under a person walking the form. It opens on the first example and turns to the next every three seconds, round the ring; ←/→ browse by hand; any key — typing, walking the rows, browsing, a press — holds the clock for a full three seconds from that key; the screen-reader tier never turns by itself. Each arriving example plays its demonstration once. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…n's ceilings `?` on the Daily limit row now says what the two ceilings are and how they meet: /budget 50 changes the day's and /budget none removes it; /budget conversation 20 gives the open conversation a smaller ceiling of its own and keeps it as the default for new ones; both hold at once and whichever is reached first stops the work — the day's everything until midnight, the conversation's just that conversation; the running turn always finishes. Each /budget wears the composer's chip. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…on the list TestModelNamesReadAsNamesAndKeepTheirLevel still expected the open list to draw "DeepSeek V4 Flash", which the flat list of exact ids stopped doing on purpose; it now asserts the two halves that hold — the field row and the typed search speak the friendly name, every row of the open list is the exact id — and leaves the flat shape itself to the test that owns it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… the setup's prose catches up The setup's foot said "esc to paste a new one" on every frame, while the keys line two rows up said "esc skips setup" whenever the controls step stood alone — a key already in the shell or the profile, only the controls asked. The line is now chosen by the same rule as the keys line: with a connect step before it, esc goes back there; standing alone, it names /connect as the door to a new key. A test pins the alone case on the same frame. The manual stops listing the review row's enter verbs (`shows them`, `goes on`) and stops saying the setup shows memory, permissions and the countdown under `Other settings`; both pages that explained esc on an expired key say the conditional thing. The comments the redesign left behind say what is true now: the example turns on a clock and the focus never moves it, the panel stands above the form, the edge label — not a foot line — is what says it is an illustration, and `codeaf telemetry show` is spoken of as the command that went. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
297c81a to
1580bb7
Compare
…oted whole The detail ran on past "whichever is reached first stops the work" into what each ceiling holds and what the provider does, which is more than a `?` on one row should say; it stops there now. Its commands are quoted whole — '/budget 50', '/budget none', '/budget conversation 20' — so a reader sees the amount is part of what is typed, and the second sentence says a conversation's smaller ceiling is set by e.g. '/budget conversation 20'. A quote is a word boundary for the command chip now, on either side: prose that says '/budget 50' is naming the command and gets the chip on its name, '/settings' is chipped without its closing quote, and a quoted path is still a path. The manual mirrors the new wording. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Quote boundaries had reached the send scan, so asking about /task could start work. Keep the original word boundaries for action; resting words and follow-up plain ranges use the transcript's quote-aware painting scan. Leave quoted door names plain after an ordinary send and in guard/revive wrappers, while live tags retain their chips. Scope the bash guard to action and draft/transcript paint; informational lines beginning with ! still chip known commands. Cover straight and curly quotes, whole-message delivery, unchanged unquoted tags, ordinary-send transcript paint, informational ! lines and the manual answer. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…g models The engine flattened refusals into text and lost the expiry-triggered balance read. Recognize that text beside provider status handling, and keep expired readings from moving untouched conversations between defaults. Cover structured and flattened refusals, excluded statuses and direct services, and document both launch roads. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Keep the no-match model list open with its row unanswered and its focus and model unchanged. Hold example turns behind one timer, including a tick queued before the latest key. Build the free-id set once per catalog pass and prove the 400-row order and membership; omit the wall-clock benchmark comparison. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…d off The settings row persisted off while the running process kept sending usage and exit events. Close the existing process gate after a successful off write; enabling waits for startup to resolve all opt-outs. Name replacement switches in the removed-command error and make the disclosure, hints and manual agree on timing, defaults and relay. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The controls explanation exceeded a standalone manual read, and the change entry still claimed removed review and example-key behavior. Split self-contained setup topics, add retrieval probes, and describe current credit, model-list and telemetry outcomes. Use the required first-run title and describe only origin/dev-to-PR invalidations, including the empty model list and telemetry switches. Split the empty-task-page answer too because the changed corpus ranking otherwise hid an existing probe; leave every existing probe unchanged. Keep the standalone section-size test; drop the transient change-entry test and duplicated exact-sentence assertion. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The engine sends the session's unauthorized ending without its typed provider refusal, so the ordinary launch missed the fresh balance read. Export one unauthorized sentence for both session spellings and match its trimmed prefix after the engine wire, under the existing refusal debounce. Keep typed expiry recognition and the direct-service exclusion; prove the real 401 ending, arbitrary key-source tails, excluded statuses and unchanged conversation defaults. Document that the read decides expiry and an invalid key leaves the previous reading alone. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A landing retained its sendable pool configuration through judging, so turning the settings switch off still allowed a later POST. Resolve the live pool ladder before adding outgoing scores and at each HTTP request, including later batches and retries; keep local scores and leave older unsent rows pending. Preserve the pool's existing behavior on source and test builds through its own configuration ladder. Prove a switch changed inside the judge sends no new request, a switch changed during the first batch stops the next one, and ordinary pushes and quiet modes still work. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Name the finished-task foot in the standalone empty-page answer and shorten it to 1,945 characters without losing facts; keep every existing retrieval probe. Remove the inaccurate claim that the previous telemetry page omitted the relay URL. Update the existing engine-read and settings-off claims to describe the shared unauthorized prefix, the 30-second debounce and pool rows whose judging was already running. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Taking over: @ZeroPoint95, I walked the first run by hand on an empty home at 130x40, 120x24 and 80x24 (clicks on every row, wheel on the list, enter walking the form,
Left for later, not changed here: a custom |
Keep the caller's resolved pool configuration instead of re-reading the process environment. Recheck the project and profile telemetry rows before recording or sending to honor live opt-outs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
One more: |
AbirAbbas
left a comment
There was a problem hiding this comment.
Verified and taken over; merging.
First-run fixes, plus the owner's follow-ups on the same screen. Every item below is in
docs/changes/unreleased/1720-onboarding-ux-cleanups.mdas an invalidates line; the manual'sgetting-started,openrouter-creditsandrunning-from-the-terminalpages follow it.New UX looks like this
1. The interactive menus
↓ enter entersends.Start a conversationleaves); the wheel scrolls the open list.2. Telemetry
--once, or ahead of a task; the "nothing sent until shown" gate goes with it.codeaf telemetry(status,info,show,on,off) is removed. The disclosure is the README's Telemetry section anddocs/TELEMETRY.md, held to the switches by the telemetry package's doc test. The switches are unchanged:/settingstelemetry toggle,CODEAF_TELEMETRY=off,DO_NOT_TRACK=1, the project file, an empty endpoint.3. OpenRouter account state
:freeids and zero-priced catalog rows) and saysfree only; the model in use stays on the list. The warning stands right-aligned on the frame's last row, where the keys row carries it outside the setup.API key expiredis a reading of its own (credits.Reading.Expired, kept beside low incredits.json).Your OpenRouter key has expired — make a new one at openrouter.ai/settings/keysstands under the message box in a conversation and on Home for every OpenRouter model, free included; the setup says it on its last row; a turn refused as expired asks for a fresh read throughprovider.APIError.KeyExpired(the taxonomy law forbids reading the status in the surface); the free defaults are not used for it.4. The controls screen itself (owner's follow-ups)
Basic settings, the keys line directly under it, then the rows. The old two-column layout,Models and spending+ lead sentence, and the panel'sAn illustration…foot line are gone.Hand off complex coding tasks, asks/senior-dev …; commands in requests, explanations and the note wear the composer's chip.←/→browse; any key holds the clock 3 s; the focus never moves it; the screen-reader tier never turns by itself.enter sets the limit · ↑↓ moves · …, notab moves, no←→ examples. The looseenterbesideStart a conversationis gone.Other settings use defaults · review) is removed; a dim noteEverything else is in /settingsstands under the way out./budget, the model's/model;?on the limit explains the day's and the conversation's ceilings and how they meet.Proof
internal/tui3,internal/credits,internal/config,internal/provider,internal/telemetry,cmd/codeaf), the manual gate has new probes, the untaggedinternal/e2eneedle gate andmake test-lawsare green, andmake test-quickis green on the branch head.↓ enter entersending, the one-column layout at 130×40 and its fallback at 120×24, the panel turning on its clock and holding on keys, the chips in the capture's escape bytes, and the expired-key warning on the welcome screen against a local stub.make pr-readyhas not been run on this branch.Open question left to the owner: the
←/→glyphs read as asymmetric in the terminal font; every mirror-image alternative is a vocabulary glyph with another meaning, so they were left as they are.A Linux arm64 build of the head is packaged as a Docker image for first-run trials (
docker run -it --rm codeaf-onboarding); the Dockerfile lives outside the repository.🤖 Generated with Claude Code